package com.jeesite.modules.warehouseposition.service;

import java.util.*;

import com.jeesite.common.collect.ListUtils;
import com.jeesite.common.config.Global;
import com.jeesite.common.idgen.IdGen;
import com.jeesite.common.lang.StringUtils;
import com.jeesite.common.service.ServiceException;
import com.jeesite.common.utils.OrgUtil;
import com.jeesite.common.utils.excel.ExcelImport;
import com.jeesite.modules.common.vo.CommonSelectDataVO;
import com.jeesite.modules.sys.utils.UserUtils;
import com.jeesite.modules.warehouse.dao.WarehouseDao;
import com.jeesite.modules.warehouse.entity.Warehouse;
import com.jeesite.modules.warehouse.entity.excel.WarehouseImport;
import com.jeesite.modules.warehouse.enums.WarehouseCategoryEnum;
import com.jeesite.modules.warehouse.enums.WarehousePositionFlagEnum;
import com.jeesite.modules.warehousearea.dao.WarehouseAreaDao;
import com.jeesite.modules.warehousearea.entity.WarehouseArea;
import com.jeesite.modules.warehouseposition.entity.excel.WarehousePositionImport;
import com.jeesite.modules.warehouseposition.entity.qo.WarehousePositionQO;
import com.jeesite.modules.warehouseposition.entity.vo.WarehousePositionVO;
import com.jeesite.modules.warehouseshelves.dao.WarehouseShelvesDao;
import com.jeesite.modules.warehouseshelves.entity.WarehouseShelves;
import com.jeesite.modules.warehouseshelves.entity.excel.WarehouseShelvesImport;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.jeesite.common.entity.Page;
import com.jeesite.common.service.CrudService;
import com.jeesite.modules.warehouseposition.entity.WarehousePosition;
import com.jeesite.modules.warehouseposition.dao.WarehousePositionDao;
import org.springframework.web.multipart.MultipartFile;

import static com.jeesite.common.web.http.ServletUtils.renderResult;

/**
 * 库位档案Service
 * @author 码脑洞
 * @version 2025-04-08
 */
@Service
public class WarehousePositionService extends CrudService<WarehousePositionDao, WarehousePosition> {
	@Autowired
	private WarehouseDao warehouseDao;
	@Autowired
	private WarehouseAreaDao warehouseAreaDao;
	@Autowired
	private WarehouseShelvesDao warehouseShelvesDao;
	
	/**
	 * 获取单条数据
	 * @param warehousePosition
	 * @return
	 */
	@Override
	public WarehousePosition get(WarehousePosition warehousePosition) {
		return super.get(warehousePosition);
	}
	
	/**
	 * 查询分页数据
	 * @param warehousePosition 查询条件
	 * @param warehousePosition page 分页对象
	 * @return
	 */
	@Override
	public Page<WarehousePosition> findPage(WarehousePosition warehousePosition) {
		return super.findPage(warehousePosition);
	}
	
	/**
	 * 查询列表数据
	 * @param warehousePosition
	 * @return
	 */
	@Override
	public List<WarehousePosition> findList(WarehousePosition warehousePosition) {
		return super.findList(warehousePosition);
	}
	
	/**
	 * 保存数据（插入或更新）
	 * @param warehousePosition
	 */
	@Override
	@Transactional
	public void save(WarehousePosition warehousePosition) {
		if (StringUtils.isBlank(warehousePosition.getCode())) {
			throw new ServiceException("库位编码不能为空");
		}

		// 检查编码唯一性
		WarehousePosition entity = dao.getWarehousePosition(warehousePosition);
		if (entity != null){
			throw new ServiceException("库位编码已存在，请重新输入");
		}
		super.save(warehousePosition);
	}
	
	/**
	 * 更新状态
	 * @param warehousePosition
	 */
	@Override
	@Transactional
	public void updateStatus(WarehousePosition warehousePosition) {
		super.updateStatus(warehousePosition);
	}
	
	/**
	 * 删除数据
	 * @param warehousePosition
	 */
	@Override
	@Transactional
	public void delete(WarehousePosition warehousePosition) {
		super.delete(warehousePosition);
	}

	public List<CommonSelectDataVO> selectWarehousePositionList() {
		return dao.selectWarehousePositionList();
	}

	public Page<WarehousePositionVO> findWarehousePositionPage(WarehousePositionQO warehousePositionQO) {
		Page<WarehousePositionVO> page = warehousePositionQO.getPage();
		warehousePositionQO.setOrgId(OrgUtil.getOrgId());
		page.setList(dao.findWarehousePositionPage(warehousePositionQO));
		return page;
	}

	public Boolean checkCodeUnique(String oldCode, String code) {
		if (StringUtils.isEmpty(code)) {
			return false;
		}
		WarehousePosition warehousePosition = new WarehousePosition();
		warehousePosition.setCode(code);
		if (code.equals(oldCode)) {
			return true;
		} else {
			return findWarehousePositionCodeOrName(warehousePosition) == null;
		}
	}

	public WarehousePosition findWarehousePositionCodeOrName(WarehousePosition warehousePosition) {
		return dao.findWarehousePositionCodeOrName(warehousePosition);
	}



	@Transactional
	public String importData(MultipartFile file) {
		// 1. 校验文件是否为空
		if (file == null || file.isEmpty()) {
			return "导入失败：文件为空，请上传有效文件！";
		}

		// 2. 校验文件格式（假设支持 CSV 和 Excel）
		String fileName = file.getOriginalFilename();
		if (fileName == null || !(fileName.endsWith(".csv") || fileName.endsWith(".xlsx"))) {
			return "导入失败：仅支持 CSV 或 Excel 文件格式！";
		}


		// 读取Excel文件中的数据
		List<WarehousePositionImport> importList;
		try {
			importList = new ExcelImport(file, 2, 0).getDataList(WarehousePositionImport.class);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}


		// 检查 importList 中是否存在重复编码
		List<String> errorMessages = new ArrayList<>();
		Set<String> codeSet = new HashSet<>();
		for (WarehousePositionImport warehousePositionImport : importList) {
			if (codeSet.contains(warehousePositionImport.getCode())) {
				return "导入失败：库位编码 [" + warehousePositionImport.getCode() + "] 在文件中重复，请检查文件内容！";
			}
			codeSet.add(warehousePositionImport.getCode());
		}

		for (int i = 0; i < importList.size(); i++) {
			WarehousePositionImport importData = importList.get(i);
			int rowNum = i + 3; // Excel行号从1开始，前两行是标题和表头

			if (StringUtils.isBlank(importData.getCode())) {
				errorMessages.add("第" + rowNum + "行：库位编码不能为空");
			}
			if (StringUtils.isBlank(importData.getName())) {
				errorMessages.add("第" + rowNum + "行：库位名称不能为空");
			}
			if (StringUtils.isBlank(importData.getWarehouseName())) {
				errorMessages.add("第" + rowNum + "行：所属仓库不能为空");
			}
			if (StringUtils.isNotBlank(importData.getCode())) {
				codeSet.add(importData.getCode());
			}
		}

		// 如果存在校验错误，一次性抛出
		if (!errorMessages.isEmpty()) {
			return renderResult(Global.FALSE, StringUtils.join(errorMessages, "; "));
		}

		// 校验编码唯一性，是否存在库中
		List<WarehousePosition> list = dao.findWarehousePositionList(new ArrayList<>(codeSet));
		if (!list.isEmpty()) {
			return renderResult(Global.FALSE, "导入失败：导入的数据存在库位编码已在数据库中");
		}

		// 收集所有仓库名称和库区名称，用于批量查询
		ArrayList<String> warehouseNames = new ArrayList<>();
		ArrayList<String> areaNames = new ArrayList<>();
		ArrayList<String> shelvesNames = new ArrayList<>();
		for (WarehousePositionImport importData : importList) {
			if (StringUtils.isNotBlank(importData.getWarehouseName()) && !warehouseNames.contains(importData.getWarehouseName())) {
				warehouseNames.add(importData.getWarehouseName());
			}
			if (StringUtils.isNotBlank(importData.getAreaName()) && !areaNames.contains(importData.getAreaName())) {
				areaNames.add(importData.getAreaName());
			}
			if (StringUtils.isNotBlank(importData.getShelvesName()) && !areaNames.contains(importData.getShelvesName())) {
				shelvesNames.add(importData.getShelvesName());
			}
		}

		// 批量查询仓库信息，建立名称到ID的映射
		Map<String, Long> warehouseNameToIdMap = new HashMap<>();
		if (!warehouseNames.isEmpty()) {
			List<Warehouse> warehouseList = warehouseDao.findWarehouseListByNames(warehouseNames);
			for (Warehouse warehouse : warehouseList) {
				warehouseNameToIdMap.put(warehouse.getName(), warehouse.getAutoId());
			}
		}

		// 批量查询库区信息，建立名称到ID的映射
		Map<String, Long> areaNameToIdMap = new HashMap<>();
		if (!areaNames.isEmpty()) {
			List<WarehouseArea> warehouseAreaList = warehouseAreaDao.findWarehouseAreaListByNames(areaNames);
			for (WarehouseArea warehouseArea : warehouseAreaList) {
				areaNameToIdMap.put(warehouseArea.getName(), warehouseArea.getAutoId());
			}
		}

		Map<String, Long> shelvesNameToIdMap = new HashMap<>();
		if (!shelvesNames.isEmpty()) {
			List<WarehouseShelves> warehouseShelvesList = warehouseShelvesDao.findWarehouseAreaListByNames(shelvesNames);
			for (WarehouseShelves warehouseShelves : warehouseShelvesList) {
				shelvesNameToIdMap.put(warehouseShelves.getName(), warehouseShelves.getAutoId());
			}
		}

		Date currentDate = new Date();
		List<WarehousePosition> warehousePositions = new ArrayList<>();
		for (WarehousePositionImport warehousePositionImport : importList) {
			WarehousePosition warehousePosition = new WarehousePosition();
			warehousePosition.setAutoId(IdGen.autoId());
			warehousePosition.setOrgId(OrgUtil.getOrgId());
			warehousePosition.setOrgCode(OrgUtil.getOrgCode());
			warehousePosition.setOrgName(OrgUtil.getOrgName());
			warehousePosition.setCode(warehousePositionImport.getCode());
			warehousePosition.setName(warehousePositionImport.getName());
			warehousePosition.setWarehouseId(warehouseNameToIdMap.get(warehousePositionImport.getWarehouseName()));
			warehousePosition.setAreaId(areaNameToIdMap.get(warehousePositionImport.getAreaName()));
			warehousePosition.setShelvesId(shelvesNameToIdMap.get(warehousePositionImport.getShelvesName()));
			warehousePosition.setStatus(WarehousePosition.STATUS_NORMAL);
			warehousePosition.setSourceType("1");
			warehousePosition.setCreateBy(UserUtils.getUser().getCreateBy());
			warehousePosition.setCreateDate(currentDate);
			warehousePosition.setUpdateBy(UserUtils.getUser().getCreateBy());
			warehousePosition.setUpdateDate(currentDate);
			warehousePositions.add(warehousePosition);
		}

		// 5. 批量保存有效数据
		if (!warehousePositions.isEmpty()) {
			try {
				ListUtils.pageList(warehousePositions, 100, objs -> dao.insertBatch((List<WarehousePosition>) objs[0]));
			} catch (Exception e) {
				return "导入失败：数据保存异常，请稍后重试！";
			}
		}
		return renderResult(Global.TRUE, "导入成功：共导入 " + warehousePositions.size() + " 条数据！");
	}

}